/*
 * Copyright 2011-2012 by The Regents of the University of California Licensed
 * under the Apache License, Version 2.0 (the "License"); you may not use this
 * file except in compliance with the License. you may obtain a copy of the
 * License from
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package edu.ucsd.db.bassarisk.storage.loading;

import edu.ucsd.db.bassarisk.data.api.IValueType;
import edu.ucsd.db.bassarisk.data.api.IValueType.IObjectValueReference;
import edu.ucsd.db.bassarisk.data.api.IValueType.ITypeTools;
import edu.ucsd.db.bassarisk.data.api.IValueType.IValueCopier;
import edu.ucsd.db.bassarisk.data.api.IValueType.IValueReference;
import edu.ucsd.db.bassarisk.storage.common.IColumnSegmentInfo;

public class ColumnSegmentInfo<VT extends IValueType> implements IColumnSegmentInfo<VT> {

  private final IObjectValueReference<VT> firstSegmentValue;
  private final IObjectValueReference<VT> lastSegmentValue;
  private final IValueCopier<VT> valueCopier;

  private long firstEntryIndex;
  private long entryCount;

  public ColumnSegmentInfo(final ITypeTools<VT> columnTypeTools) {
    this.valueCopier = columnTypeTools.getGenericCopyer();
    this.firstSegmentValue = columnTypeTools.newReference();
    this.lastSegmentValue = columnTypeTools.newReference();
  }

  public void append(final ColumnSegmentInfo<VT> appendingSegmentInfo) {
    this.entryCount += appendingSegmentInfo.entryCount;
    this.valueCopier.copy(appendingSegmentInfo.lastSegmentValue,
                          this.lastSegmentValue);
  }

  @Override
  public long getEntryCount() {
    return this.entryCount;
  }

  @Override
  public long getFirstEntryIndex() {
    return this.firstEntryIndex;
  }

  @Override
  public IObjectValueReference<VT> getFirstValue() {
    return this.firstSegmentValue;
  }

  @Override
  public IObjectValueReference<VT> getLastValue() {
    return this.lastSegmentValue;
  }

  @Override
  public boolean hasEntry(final long entryIndex) {
    return entryIndex >= this.firstEntryIndex
        && entryIndex < (this.firstEntryIndex + this.entryCount);
  }

  public long incrementEntryCount() {
    return ++this.entryCount;
  }

  public void reset(final int firstEntryIndex) {
    this.reset(0, firstEntryIndex);
  }

  public void reset(final long entryCount, final long firstEntryIndex) {
    this.firstEntryIndex = firstEntryIndex;
    this.entryCount = entryCount;
    this.firstSegmentValue.resetDefault();
    this.lastSegmentValue.resetDefault();
  }

  public void setFirstValue(final IValueReference<VT> newValue) {
    this.valueCopier.copy(newValue, this.firstSegmentValue);
  }

  public void setLastValue(final IValueReference<VT> newValue) {
    this.valueCopier.copy(newValue, this.lastSegmentValue);
  }

}